using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;
using Yoozoo.Libs;
using Yoozoo.Managers;
using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Config;
using Yoozoo.Mars.Got;

namespace Gameplay.PVE
{
    public class SkillDirectorComponennt : IComponent,ITransmit
    {
        //战斗组件
        private BattleUnit unit;
        private PveSkillConfig skillConfig;
        private PveSkillBulletConfig firstBulletConfig;
        private GameObject director;
        private int directorResId;
        private GameObject rangeDirector;
        private int rangeDirectorResId;
        private GameObject directorAlert;
        private GameObject directorArrow;
        
        private Vector3 targetPosition;
        private Vector3 targetForward;
        private List<UnitBase> targetList = new List<UnitBase>();

        private List<Material> directorMats = new List<Material>();
        private bool considerObstacle;
        private bool isAvailable;
        private int obstacleWidth;
        private int obstacleHeight;

        private Vector3 rectRangeCenter;
        private float rectRangeWidth;
        private float rectRangeHeight;
        
        private int summonUnitId;
        private Color directorOriginColor;
        
        private Vector3 directorPosition;

        private List<GameObject> summonUnitList = new List<GameObject>();

        private RpgSummonConfig summonConfig;

        private Dictionary<Renderer, Material[]> summonMatList = new Dictionary<Renderer, Material[]>();

        private int currentSkillIndex;
        
        private bool isSwitchingWeapon = false;

        void IClass.OnReset()
        {
            summonUnitId = 0;
            skillConfig = null;
        }

        void IComponent.OnInitialize(UnitBase unit)
        {
            this.unit = unit as BattleUnit;
        }
        public void Initialize(UnitBase unit)
        {
            ((IComponent)this).OnInitialize(unit);
        }

        public void Birth()
        {
            ((IComponent)this).OnBirth();
        }
        
        public void Update()
        {
            ((IComponent) this).OnUpdate();
        }
        
        public void Dispose()
        {
            ((IClass)this).OnReset();
        }

        void IComponent.OnUpdate()
        {
            
        }

        void IComponent.OnBirth()
        {
            
        }

        void IComponent.OnDead()
        {
            
        }

        private GameObject GetRangeDirector(float radius)
        {
            rangeDirectorResId = 4;
            var rangeDirector = PveResourceManager.GetResource(PveResourceManager.EPveResType.Director,
                rangeDirectorResId);
            if (rangeDirector != null)
            {
                rangeDirector.transform.SetParent(PveScene.pveRootTrans);
                float localScale = 1f;
                rangeDirector.transform.localScale =
                    new Vector3(localScale, localScale, localScale) * radius;
                /*float localScale = 1f;
                var projector = rangeDirector.GetComponentInChildren<Projector>();
                projector.orthographicSize = radius;
                projector.transform.localPosition = new Vector3(0,0.2f,0f);*/
                rangeDirector.transform.position = unit.Data.position;
                rangeDirector.SetLayerRecursively(PveUtils.blackScreenLayer);
            }
            return rangeDirector;
        }

        private GameObject GetRectRangeDirector()
        {
            var width = rectRangeWidth;
            var height = rectRangeHeight;
            var center = rectRangeCenter;
            rangeDirectorResId = 2;
            var rangeDirector = PveResourceManager.GetResource(PveResourceManager.EPveResType.Director,
                rangeDirectorResId);
            if (rangeDirector != null)
            {
                rangeDirector.transform.SetParent(PveScene.pveRootTrans);
                /*var projector = rangeDirector.GetComponentInChildren<Projector>();
                projector.aspectRatio = width / height;
                projector.orthographicSize = height / 2;
                projector.transform.localPosition = new Vector3(0,0.2f,0);*/
                rangeDirector.transform.localScale = new Vector3(width / 2, 0.2f, height / 2);
                rangeDirector.transform.position = center;
                rangeDirector.transform.forward = Vector3.right;
                var cube = rangeDirector.transform.Find("Cube");
                cube.localPosition = new Vector3(0,0,0);
            }
            return rangeDirector;
        }
        
        private GameObject projector;

        private GameObject GetDirector(bool isInBlackScreen = true)
        {
            GameObject director = null;
            directorMats.Clear();
            if (skillConfig.summon_id != 0)
            {
                Vector3 forward = Vector3.forward;
                summonConfig = PveUtils.GetRpgSummonConfig(skillConfig.summon_id);
                if (summonConfig.type == 0)
                {
                    var config = PveUtils.GetRpgMonsterConfig(summonConfig.summon_id);
                    var modelConfig = PveUtils.GetRpgModelConfig(config.model_id);
                    summonUnitId = modelConfig.res_id;
                    forward = unit.Data.team == 0 ? Vector3.right : Vector3.left;
                }
                else if (summonConfig.type == 1)
                {
                    var config = PveUtils.GetRpgObstacleConfig(summonConfig.summon_id);
                    summonUnitId = config.res_id;
                    considerObstacle = true;
                    obstacleHeight = (int) config.height;
                    obstacleWidth = (int) config.width;
                }
                
                director = new GameObject("summon");
                director.transform.SetParent(PveScene.pveRootTrans);
                summonUnitList.Clear();
                summonMatList.Clear();
                
                for (int i = 0; i < summonConfig.positions.Count; i++)
                {
                    var unit = PveResourceManager.GetResource(PveResourceManager.EPveResType.Model,
                        summonUnitId);
                    unit.transform.SetParent(director.transform);
                    var f = this.unit.Data.team == 0 ? Vector3.right : Vector3.left;
                    var offset = Quaternion.AngleAxis(PveUtils.GetAngle(f,Vector3.forward),Vector3.up) * new Vector3(summonConfig.positions[i].x / 1000f,0,summonConfig.positions[i].y / 1000f);
                    unit.transform.localPosition = offset;
                    unit.transform.forward = forward;
                    if (summonConfig.summon_show_type == 0)
                    {
                        var renderers = unit.GetComponentsInChildren<SkinnedMeshRenderer>();
                        for (int j = 0; j < renderers.Length; j++)
                        {
                            Material[] newMats = new Material[renderers[j].sharedMaterials.Length];
                            for (int k = 0; k < renderers[j].sharedMaterials.Length; k++)
                            {
                                var mat = PveResourceManager.GetWireMat();
                                newMats[k] = mat;
                                directorOriginColor = mat.GetColor("_TintColor");
                                directorMats.Add(mat);
                            }
                            summonMatList.Add(renderers[j], renderers[j].materials);
                            renderers[j].materials = newMats;
                        }
                        var renderers2 = unit.GetComponentsInChildren<MeshRenderer>();
                        for (int j = 0; j < renderers2.Length; j++)
                        {
                            Material[] newMats = new Material[renderers2[j].sharedMaterials.Length];
                            for (int k = 0; k < renderers2[j].sharedMaterials.Length; k++)
                            {
                                var mat = PveResourceManager.GetWireMat();
                                newMats[k] = mat;
                                directorOriginColor = mat.GetColor("_TintColor");
                                directorMats.Add(mat);
                            }
                            summonMatList.Add(renderers2[j], renderers2[j].materials);
                            renderers2[j].materials = newMats;
                        }
                    }
                    else if (summonConfig.summon_show_type == 1)
                    {
                        var animator = unit.gameObject.GetComponentInChildren<Animator>();
                        if (animator != null)
                        {
                            animator.ResetTrigger("Idle");
                            animator.SetTrigger("Idle");
                            animator.ResetTrigger("SummonDisplay");
                            animator.SetTrigger("SummonDisplay");
                            animator.Update(0); 
                            animator.speed = 0;
                            //animator.Update(1);
                            //animator.speed = 0;
                            if (summonUnitId == 10000) //小飞机
                            {
                                animator.gameObject.transform.localPosition = new Vector3(0, Random.Range(2f, 3f), 0);
                            }
                        }
                    }
                    summonUnitList.Add(unit);
                }
                
                director.SetLayerRecursively(PveUtils.blackScreenLayer);
                director.transform.forward = forward;
            }
            else
            {
                directorResId = PveTargetSearchHelper.GetDirectorResourceByBulletConfig(firstBulletConfig);
                director = PveResourceManager.GetResource(PveResourceManager.EPveResType.Director, directorResId);
            }
            

            if (director == null)
            {
                return director;
            }
            director.transform.SetParent(PveScene.pveRootTrans);
            if (firstBulletConfig.director_type == 1)
            {
                float localScale = 1f;
                float radius = 1;
                firstBulletConfig.director_args.TryGetValue("radius", out radius);
                director.transform.localScale = new Vector3(localScale, localScale, localScale) * radius;
                director.SetLayerRecursively(PveUtils.blackScreenLayer);
                //director.transform.localScale = new Vector3(localScale, localScale, localScale) * radius;
                /*var projector = director.GetComponentInChildren<Projector>();
                projector.orthographicSize = radius - 0.5f;
                projector.transform.localPosition = new Vector3(0,0.2f,0.25f);
                directorMats.Add(projector.material);*/
            }
            else if (firstBulletConfig.director_type == 0)
            {
                float localScale = 0.3f;
                //var projector = director.GetComponentInChildren<Projector>();
                //directorMats.Add(projector.material);
                director.transform.localScale = new Vector3(localScale, localScale, localScale);
                director.SetLayerRecursively(PveUtils.blackScreenLayer);
            }
            else if (firstBulletConfig.director_type == 3 || firstBulletConfig.director_type == 5)
            {
                float localScale = 1f;
                float radius = 1;
                firstBulletConfig.director_args.TryGetValue("radius", out radius);
                director.transform.localScale = new Vector3(localScale, localScale, localScale) * radius;
                director.SetLayerRecursively(PveUtils.blackScreenLayer);
                //var projector = director.GetComponentInChildren<Projector>();
                //projector.orthographicSize = radius;
                //projector.transform.localPosition = new Vector3(0,0.2f,0f);
                //directorMats.Add(projector.material);
            }
            else if (firstBulletConfig.director_type == 2)
            {
                float width;
                firstBulletConfig.director_args.TryGetValue("width", out width);
                float height;
                firstBulletConfig.director_args.TryGetValue("height", out height);
                director.transform.localScale = new Vector3(width, 1, height);
                director.SetLayerRecursively(PveUtils.blackScreenLayer);
                var cube = director.transform.Find("Cube");
                cube.transform.localPosition = new Vector3(0,0,1);
                //var projector = director.GetComponentInChildren<Projector>();
                //projector.aspectRatio = width / height;
                //projector.orthographicSize = height / 2 - 0.5f;
                //projector.transform.localPosition = new Vector3(0,0.2f,(height / 2 + 0.25f));
                //directorMats.Add(projector.material);
            }
            else if (firstBulletConfig.director_type == 10)
            {
                director.transform.localScale = new Vector3(PveUtils.globalRatio, PveUtils.globalRatio,
                    PveUtils.globalRatio);
            }

            if (isInBlackScreen)
            {
                //director.SetLayerRecursively(PveUtils.blackScreenLayer);
            }
            return director;
        }

        private void OnShowDirector(int skillId)
        {
            currentSkillIndex = UnitManager.Instance.globalSkillIndex;
            unit.Transmit(ETransmitType.CancelAim);
            skillConfig = PveUtils.GetSkillConfig(skillId);
            firstBulletConfig = PveUtils.GetSkillBulletConfig((int) skillConfig.bullets[0].y);
            rectRangeCenter = Vector3.zero;
            rectRangeWidth = 0;
            rectRangeHeight = 0;
            if (director == null)
            {
                isAvailable = true;
                considerObstacle = false;
                director = GetDirector();
                if (firstBulletConfig.director_args != null)
                {
                    if (firstBulletConfig.director_args.TryGetValue("distance", out var radius))
                    {
                        rangeDirector = GetRangeDirector(radius);
                    }
                    else if (firstBulletConfig.director_args.TryGetValue("centerX",out var centerX) && firstBulletConfig.director_args.TryGetValue("centerZ",out var centerZ))
                    {
                        var center = new Vector3(centerX, 0, centerZ) +
                                     PveManager.Instance.GetRpgStageCenterPosition();
                        float height = 0;
                        float width = 0;
                        firstBulletConfig.director_args.TryGetValue("width", out width);
                        firstBulletConfig.director_args.TryGetValue("height", out height);
                        rectRangeCenter = center;
                        rectRangeWidth = width;
                        rectRangeHeight = height;
                        rangeDirector = GetRectRangeDirector();
                    }
                }

                /*if (firstBulletConfig.director_type != 2 && firstBulletConfig.director_type != 1 && firstBulletConfig.director_type != 4 && skillConfig.weapon_id == 0)
                {
                    directorArrow = PveResourceManager.GetResource(PveResourceManager.EPveResType.Director, 10);
                    if (directorArrow != null)
                    {
                        directorArrow.SetLayerRecursively(PveUtils.blackScreenLayer);
                        directorArrow.transform.SetParent(PveScene.pveRootTrans);
                    }
                }*/
                
                unit.SetLayer(PveUtils.blackScreenLayer);

                if (summonUnitId != 0)
                {
                    /*var animator = director.GetComponentInChildren<Animator>();
                    if (animator != null)
                    {
                        animator.SetTrigger("Idle");
                        animator.Update(0);
                        animator.speed = 0;
                    }*/
                    if (considerObstacle)
                    {
                        MoveDirector(GetObstacleAutoPosition(),director);
                    }
                    else
                    {
                        MoveDirector(unit.Data.position + unit.Data.forward,director);
                    }

                    CheckTarget();
                    return;
                }
                
                PveTargetSearchHelper.GetCandidates(unit,skillConfig,ref candidates);

                for (int i = 0; i < candidates.Count; i++)
                {
                    if (candidates[i].gameObject != null)
                    {
                        candidates[i].gameObject.SetLayerRecursively(PveUtils.blackScreenLayer);
                    }
                }
                
                SetDirectorAvailable(true);
            }


            var targetPosition = unit.Data.position + unit.Data.forward;
            if (candidates != null && candidates.Count > 0)
            {
                if (skillConfig.search_sort == 0)
                {
                    if (unit.Data.lockTarget != null && unit.Data.lockTarget.Data.team == unit.Data.GetTargetTeam(skillConfig.search_team))
                    {
                        targetPosition = unit.Data.lockTarget.Data.position;
                    }
                    else
                    {
                        targetPosition = candidates[0].Data.position;
                    }
                }
                else
                {
                    targetPosition = PveTargetSearchHelper.GetAutoSkillPosition(ref candidates, firstBulletConfig, unit,skillConfig.search_sort);
                }
            }
            MoveDirector((targetPosition),director);
            CheckTarget();
        }

        private void OnHideDirector(bool isUseSkillSuccess = true)
        {
            if (director != null)
            {
                director.gameObject.SetLayerRecursively(PveUtils.pveUnitLayer);
                if (summonUnitId == 0)
                {
                    PveResourceManager.RecoverResource(director,PveResourceManager.EPveResType.Director,
                        directorResId);
                }
                else
                {
                    foreach (var item in summonMatList)
                    {
                        item.Key.materials = item.Value;
                    }

                    
                    if (summonConfig.summon_show_type == 0 || isUseSkillSuccess == false)
                    {
                        for (int i = 0; i < summonUnitList.Count; i++)
                        {
                            PveResourceManager.RecoverResource(summonUnitList[i],PveResourceManager.EPveResType.Model,
                                summonUnitId);
                        }
                        summonUnitList.Clear();
                    }
                    else if (summonConfig.summon_show_type == 1)
                    {
                        for (int i = 0; i < summonUnitList.Count; i++)
                        {
                            UnitManager.Instance.AddToSummonDic(currentSkillIndex, i, summonUnitList[i]);
                        }
                        summonUnitList.Clear();
                    }
                    GameObject.Destroy(director);
                }
                
                director = null;
            }

            if (directorArrow != null)
            {
                PveResourceManager.RecoverResource(directorArrow,PveResourceManager.EPveResType.Director,
                    10);
                directorArrow = null;
            }
            
            if (rangeDirector != null)
            {
                rangeDirector.gameObject.SetLayerRecursively(PveUtils.pveUnitLayer);
                PveResourceManager.RecoverResource(rangeDirector,PveResourceManager.EPveResType.Director,
                    rangeDirectorResId);
                rangeDirector = null;
            }
            for (int i = 0; i < targetList.Count; i++)
            {
                targetList[i].Transmit(ETransmitType.OnUnSelectBySkill);
            }
            
            unit.SetLayer(PveUtils.pveUnitLayer);
            
            
            for (int i = 0; i < candidates.Count; i++)
            {
                if (candidates[i].gameObject != null)
                {
                    candidates[i].gameObject.SetLayerRecursively(PveUtils.pveUnitLayer);
                }
            }
            
            summonUnitId = 0;
            summonUnitList.Clear();
            summonMatList.Clear();
        }

        private void OnSkillRelease(int cardIndex)
        {
            UnitManager.Instance.globalSkillIndex++;
                
            var order = ClassManager.Get<UnitOrder>();
            order.type = UnitOrder.EOrderType.Skill;
            order.targetPosition = targetPosition;
            order.skillArgs = new UnitOrder.SkillArgs
            {
                targetPosition = targetPosition,
                id = skillConfig.id,
                targetForward = targetForward,
                targetList = targetList,
                globalSkillIndex = currentSkillIndex,
            };
            var orderArg = ClassManager.Get<AddOrderTransmitArg>();
            orderArg.order = order;
            if (isSwitchingWeapon)
            {
                for (int i = 0; i < targetList.Count; i++)
                {
                    targetList[i].Transmit(ETransmitType.AddOrder,orderArg);
                }
            }
            else
            {
                unit.Transmit(ETransmitType.AddOrder,orderArg);
            }
                
            ClassManager.Free(orderArg);
            PveCardManager.Instance.Cast(cardIndex);
        }
        
        void ITransmit.OnTransmit(ETransmitType type, BaseTransmitArg arg)
        {
            if (type == ETransmitType.ShowDirector)
            {
                var sarg = arg as SkillDirectorShowArg;
                OnShowDirector(sarg.skillId);
            }
            else if (type == ETransmitType.HideDirector)
            {
                var sarg = arg as HideDirectorArg;
                OnHideDirector(sarg.isUseSkillSuccess);
            }
            else if (type == ETransmitType.AutoUseSkillSelect)
            {
                var aarg = ClassManager.Get<AutoUseSkillArg>();
                
                OnShowDirector(skillConfig.id);
                OnHideDirector();
                aarg.targetPosition = targetPosition;
                aarg.targetForward = aarg.targetPosition - unit.Data.position;
                aarg.targetList = targetList;
                aarg.skillIndex = currentSkillIndex;
                unit.Transmit(ETransmitType.AutoUseSkill,aarg);
            }
            else if (type == ETransmitType.SkillReleaseAuto)
            {
                var sarg =  arg as SkillDirectorShowArg;
                OnShowDirector(sarg.skillId);
                OnHideDirector();
                OnSkillRelease(sarg.cardIndex);
            }
            else if (type == ETransmitType.SkillRelease)
            {
                OnSkillRelease((arg as SkillReleaseArg).cardIndex);
            }
            else if (type == ETransmitType.SkillDirectorMove)
            {
                if (director != null)
                {
                    var pos = (arg as SkillDirectorMoveArg).position;
                    MoveDirector(pos,director);
                    if (unit.Data.manualForward.sqrMagnitude > 0 || isSwitchingWeapon || true)
                    {
                        
                    }
                    else
                    {
                        unit.Data.SetTargetForward(targetForward);
                        unit.Data.forward = targetForward.normalized;
                    }
                    
                    CheckTarget();
                    MoveArrow();
                    directorPosition = pos;
                    if (rangeDirector != null && rectRangeCenter == Vector3.zero)
                    {
                        rangeDirector.transform.position = unit.Data.position;
                    }
                }
            }
            else if (type == ETransmitType.ToRPG)
            {
                var skillId = unit.Data.rpgSkillId;
                skillConfig = PveUtils.GetSkillConfig(skillId);
                if (skillConfig != null)
                {
                    firstBulletConfig = PveUtils.GetSkillBulletConfig((int) skillConfig.bullets[0].y);
                }
            }
            else if (type == ETransmitType.ShowDirectorAlert)
            {
                directorAlert = GetDirector(false);
                var pos = (arg as SkillDirectorMoveArg).position;
                MoveDirector(pos,directorAlert);
            }
            else if (type == ETransmitType.HideDirectorAlert)
            {
                if (directorAlert != null)
                {
                    directorAlert.gameObject.SetLayerRecursively(PveUtils.pveUnitLayer);
                    if (summonUnitId == 0)
                    {
                        PveResourceManager.RecoverResource(directorAlert,PveResourceManager.EPveResType.Director,
                            firstBulletConfig.director_type);
                    }
                    else
                    {
                        PveResourceManager.RecoverResource(directorAlert,PveResourceManager.EPveResType.Model,
                            summonUnitId);
                    }
                    directorAlert = null;
                }
            }
            else if (type == ETransmitType.UnitBorn)
            {
                if (director != null && skillConfig != null)
                {
                    PveTargetSearchHelper.GetCandidates(unit,skillConfig,ref candidates);
                    CheckTarget();
                }
            }
        }

        private Vector3 GetObstacleAutoPosition()
        {
            var team = UnitManager.Instance.GetAllUnitByTeam(unit.Data.team);
            for (int i = 0; i < team.Count; i++)
            {
                var target = team[i];
                var avaliable = target.Data.isCanSquat && !target.Data.isHiding && !target.Data.isGoingToHidePoint && target.Data.selectable;
                if (avaliable)
                {
                    var position = target.Data.position;
                    if (PveTargetSearchHelper.GetObstacleAutoPosition(ref position, obstacleWidth, obstacleHeight,5,GetPositionByRegion))
                    {
                        return position;
                    }
                }
            }
            Debug.LogEditorError("没有找到合适的人物释放障碍物");
            var p = unit.Data.position;
            if (PveTargetSearchHelper.GetObstacleAutoPosition(ref p, obstacleWidth, obstacleHeight,10,GetPositionByRegion))
            {
                return p;
            }
            Debug.LogEditorError("没有找到合适的位置释放障碍物");
            return unit.Data.position + unit.Data.forward;
        }
        
        private Vector3 GetPositionByRegion(Vector3 position)
        {
            var region = PveManager.Instance.GetRpgStageRegion();
            float radiusMinus = 0;
            if (firstBulletConfig.director_type == 3)
            {
                firstBulletConfig.director_args.TryGetValue("radius", out radiusMinus);
            }

            var regionXMax = region.x;
            var regionXMin = region.y;
            var regionZMax = region.z;
            var regionZMin = region.w;
            var x = Mathf.Min(regionXMax - radiusMinus, position.x);
            x = Mathf.Max(regionXMin + radiusMinus, x);
            var z = Mathf.Min(regionZMax - radiusMinus, position.z);
            z = Mathf.Max(regionZMin + radiusMinus, z);

            var height = rectRangeHeight;
            var width = rectRangeWidth;
            if (considerObstacle)
            {
                width -= obstacleWidth;
                height -= obstacleHeight;
            }
            
            if (rectRangeCenter != Vector3.zero)
            {
                float xMin = rectRangeCenter.x - height / 2;
                float xMax = rectRangeCenter.x + height / 2;
                float zMin = rectRangeCenter.z - width / 2;
                float zMax = rectRangeCenter.z + width / 2;
                x = Mathf.Min(x, xMax);
                x = Mathf.Max(x, xMin);
                z = Mathf.Min(z, zMax);
                z = Mathf.Max(z, zMin);
            }

            var final = new Vector3(x,0,z);
            if (summonUnitId != 0)//召唤物
            {
                if (considerObstacle) //障碍物
                {
                    var config = PveUtils.GetRpgObstacleConfig(summonConfig.summon_id);
                    for (int i = 0; i < config.hide_points.Count; i++)
                    {
                        //检查每个掩体点是否都在屏幕内
                        var playerWidthOffset = new Vector3(-0.7f,0,-0.7f);
                        var hidePoint = final + config.hide_points[i] / 10000f + playerWidthOffset;
                        var screenPosition = PveCameraManager.Instance.mainCamera.WorldToScreenPoint(hidePoint);
                        float leftLimit = 0f / 1334 * Screen.width;
                        if (screenPosition.x < leftLimit)
                        {
                            screenPosition.x = leftLimit;
                        }
                        float bottomLimit = 0f / 750 * Screen.width;
                        if (screenPosition.y < bottomLimit)
                        {
                            screenPosition.y = bottomLimit;
                        }

                        final = GetGroundPositionByScreenPosition(screenPosition) - config.hide_points[i] / 10000f - playerWidthOffset;
                    }
                }
                else
                {
                    var screenPosition = PveCameraManager.Instance.mainCamera.WorldToScreenPoint(final);
                    float leftLimit = 100f / 1334 * Screen.width;
                    if (screenPosition.x < leftLimit)
                    {
                        screenPosition.x = leftLimit;
                    }


                    final = GetGroundPositionByScreenPosition(screenPosition);
                }
            }
            return final;
        }
        
        private Vector3 GetGroundPositionByScreenPosition(Vector2 pos)
        {
            Ray ray = PveCameraManager.Instance.mainCamera.ScreenPointToRay(new Vector3(pos.x, pos.y, 0f));
                
            var origin = ray.origin;
            var direction = ray.direction;
            var p = origin.y / direction.y;
            return origin - direction * p;
        }
        
        private void MoveDirector(Vector3 position,GameObject director)
        {
            if (director == null)
            {
                return;
            }

            position = GetPositionByRegion(position);

            if (summonUnitId != 0)//召唤物
            {
                float maxDistance;
                firstBulletConfig.director_args.TryGetValue("distance", out maxDistance);
                Vector3 dir = position - unit.Data.position;
                dir.y = 0;
                if (maxDistance > 0)
                {
                    if (maxDistance * maxDistance < dir.sqrMagnitude)
                    {
                        targetPosition = unit.Data.position + dir.normalized * maxDistance;
                    }
                    else
                    {
                        targetPosition = position;
                    }
                }
                else
                {
                    targetPosition = position;
                }
                director.transform.position = targetPosition;
                director.transform.forward = Vector3.forward;
                //director.transform.forward = dir;
                //director.transform.forward = unit.Data.forward;
                //targetForward = unit.Data.team == 0 ? Vector3.right : Vector3.left;
                //director.transform.forward = targetForward;
                targetForward = dir;
            }
            else if (firstBulletConfig.director_type == 1)
            {
                targetPosition = position;
                var pos = new Vector3(unit.Data.position.x, 0, unit.Data.position.z);
                targetForward = position - pos;
                director.transform.position = unit.Data.position;
                if (targetForward != Vector3.zero)
                {
                    director.transform.forward = targetForward;
                }
               
            }
            else if (firstBulletConfig.director_type == 0)
            {
                targetForward = position - unit.Data.position;
                float maxDistance;
                if (firstBulletConfig.director_args != null && firstBulletConfig.director_args.TryGetValue("distance", out maxDistance))
                {
                    if (maxDistance < targetForward.magnitude)
                    {
                        targetPosition = unit.Data.position + targetForward.normalized * maxDistance;
                    }
                    else
                    {
                        targetPosition = position;
                    }
                }
                else
                {
                    targetPosition = position;
                }

                director.transform.position = targetPosition;
            }
            else if (firstBulletConfig.director_type == 3 || firstBulletConfig.director_type == 5)
            {
                targetPosition = position;
                targetForward = position - unit.Data.position;
                director.transform.position = position;
                //director.transform.forward = targetForward;
            }
            else if (firstBulletConfig.director_type == 2)
            {
                Vector3 dir = position - unit.Data.position;
                dir.y = 0;
                targetPosition = position;
                targetForward = dir.normalized;
                targetPosition.y = 0;
                director.transform.position = unit.Data.position + targetForward * 0.1f;
                if (targetForward != Vector3.zero)
                {
                    director.transform.forward = targetForward;
                }
            }
            else if (firstBulletConfig.director_type == 10)
            {
                float maxDistance;
                firstBulletConfig.director_args.TryGetValue("distance", out maxDistance);
                Vector3 dir = position - unit.Data.position;
                dir.y = 0;
                if (maxDistance * maxDistance < dir.sqrMagnitude)
                {
                    targetPosition = unit.Data.position + dir.normalized * maxDistance;
                }
                else
                {
                    targetPosition = position;
                }
                targetForward = dir.normalized;
                targetPosition.y = 0;
                director.transform.position = targetPosition;
                if (targetForward != Vector3.zero)
                {
                    director.transform.forward = targetForward;
                }
            }
            else
            {
                targetPosition = position;
                targetForward = targetPosition - unit.Data.position;
            }

            //Debug.LogError(Vector3.Distance(position,unit.Data.position));
            if (considerObstacle)
            {
                if (PveTargetSearchHelper.CheckDirector(targetPosition,obstacleWidth,obstacleHeight))
                {
                    SetDirectorAvailable(true);
                    targetPosition = position;
                }
                else
                {
                    if (PveTargetSearchHelper.GetObstacleAutoPosition(ref position, obstacleWidth, obstacleHeight,7,GetPositionByRegion))
                    {
                        //SetDirectorAvailable(true);
                        MoveDirector(position,director);
                        //return position;
                    }
                    else
                    {
                        SetDirectorAvailable(false);
                    }
                }
                /*else
                {
                    SetDirectorAvailable(false);
                }*/
            }
        }
        
        private List<UnitBase> candidates = new List<UnitBase>();

        private void SetDirectorAvailable(bool available)
        {
            for (int i = 0; i < directorMats.Count; i++)
            {
                directorMats[i].SetColor("_TintColor",available ? directorOriginColor : new Color(1f,0,0,1));
            }
            isAvailable = available;
        }

        private void MoveArrow()
        {
            if (directorArrow != null)
            {
                directorArrow.transform.position = unit.Data.position;
                directorArrow.transform.forward = targetPosition - unit.Data.position;
                float distance = Vector3.Distance(unit.Data.position, targetPosition);
                directorArrow.transform.localScale = new Vector3(1,distance * 0.35f,distance * 0.17f);
            }

        }
        
        private void CheckTarget()
        {
            for (int i = 0; i < targetList.Count; i++)
            {
                targetList[i].Transmit(ETransmitType.OnUnSelectBySkill);
            }

            PveTargetSearchHelper.CheckTarget(firstBulletConfig, unit.Data.position, targetPosition, targetForward,
                ref candidates, ref targetList);
            //单体技能自动吸附
            if (firstBulletConfig.director_type == 0 && targetList.Count > 0)
            {
                targetPosition = targetList[0].Data.position;
                targetForward = targetList[0].Data.position - unit.Data.position;
                if (unit.Data.manualForward.sqrMagnitude > 0.01f || isSwitchingWeapon || true)
                {
                    
                }
                else
                {
                    unit.Data.SetTargetForward(targetForward);
                    unit.Data.forward = targetForward.normalized;
                }
                director.transform.position = targetPosition;
            }

            for (int i = 0; i < targetList.Count; i++)
            {
                targetList[i].Transmit(ETransmitType.OnSelectBySkill);
            }
        }
    }
}
